package com.example.redis.bit.domain;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.example.redis.bit.domain.init.BitMapDataInit;
import com.example.redis.bit.domain.init.HyperLogDataInit;
import com.example.redis.bit.enums.DataModeEnum;
import org.redisson.api.RHyperLogLog;
import org.redisson.api.RedissonClient;
import org.redisson.client.RedisConnection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Component
public class HyperLogDomain implements IActDomain {

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private RedisConnection redisConnection;

    @Override
    public DataModeEnum getMode() {
        return DataModeEnum.HYPERLOGLOG;
    }

    @Override
    public void initData() {
        new Thread(new HyperLogDataInit()).start();
    }

    @Override
    public long countUsers(String date) {
        Date dateKey = DateUtil.parse(date, DatePattern.PURE_DATE_PATTERN);
        String key = DateUtil.formatDate(dateKey);
        RHyperLogLog hyperLogLog = redissonClient.getHyperLogLog(key);
        return hyperLogLog.count();
    }

    @Override
    public long mem(String date) {
        Date dateKey = DateUtil.parse(date, DatePattern.PURE_DATE_PATTERN);
        String key = DateUtil.formatDate(dateKey);
        RHyperLogLog hyperLogLog = redissonClient.getHyperLogLog(key);
        return hyperLogLog.sizeInMemory();
    }

    @Override
    public long act(String dateBegin, String dateEnd) {
        String resultKey = "RESULT_" + System.currentTimeMillis();
        RHyperLogLog hyperLogLog = redissonClient.getHyperLogLog(resultKey);

        Date dateBeginObj = DateUtil.parse(dateBegin, DatePattern.PURE_DATE_PATTERN);
        Date dateEndObj = DateUtil.parse(dateEnd, DatePattern.PURE_DATE_PATTERN);
        long cnt = DateUtil.betweenDay(dateBeginObj,dateEndObj,true);
        List<String> keyList = new ArrayList<>();
        for (int i = 0; i <= cnt ; i++) {
            Date currDate = DateUtil.offsetDay(dateBeginObj,i);
            String key = DateUtil.formatDate(currDate);
            keyList.add(key);
        }

        hyperLogLog.mergeWith(keyList.toArray(new String[]{}));
        long result = hyperLogLog.count();
        redissonClient.getKeys().delete(resultKey);
        return result;
    }
}
